package com.thingple.usb.manager;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
import android.util.Log;

import com.thingple.usb.session.UsbSession;
import com.thingple.usb.session.UsbSessionImpl;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class UsbDeviceManagerImpl extends UsbDeviceScanner implements UsbDeviceManager {

    private static final String TAG = UsbDeviceManagerImpl.class.getName();

    protected boolean monitorEnabled = false;
    private Context ctx;

    public UsbDeviceManagerImpl(Context ctx) throws Exception {
        init(ctx);
        startMonitor();// 自动启动监听器
    }

    @Override
    @SuppressLint("UnspecifiedRegisterReceiverFlag")
    public void startMonitor() {
        if (monitorEnabled) {
            return;
        }
        monitorEnabled = true;
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_USB_PERMISSION);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        this.ctx.registerReceiver(this, filter);
    }

    private void init(Context ctx) throws Exception {
        this.ctx = ctx;
        usbManager = ctx.getSystemService(UsbManager.class);
        if (usbManager == null) {
            throw new Exception("no usb manager");
        }
    }

    private DeviceListener listener;
    public void setListener(DeviceListener listener) {
        this.listener = listener;
    }

    public @Nullable UsbSession createSession(@NotNull UsbAccessory device, int baudRate) {
        if (!usbManager.hasPermission(device)) {
            Log.d(TAG, "无权限");
            return null;
        }
        UsbSession session = null;
        try{
            Log.d(TAG, "创建session");
            session = new UsbSessionImpl(usbManager, device, baudRate);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return session;
    }

    @Override
    protected void onDeviceAttached(@NotNull UsbAccessory device) {
        Log.d(TAG, "usb attached");
        Log.d(TAG, "attach:" + device.getModel() + "," + device.getManufacturer());
        if (listener != null) {
            listener.onDeviceAttach(device);
        }
        if (!usbManager.hasPermission(device)) {
            Log.d(TAG, "request usb device access permission");
            UsbManagerWrapper.requestPermission(ctx, usbManager, device);
        } else {
            if (listener != null) {
                listener.onDeviceAllowed(device);
            }
        }
    }

    @Override
    protected void onDeviceDetached(@NotNull UsbAccessory device) {
        Log.d(TAG, "usb detached");
        if (listener != null) {
            listener.onDeviceDetach(device);
        }
    }

    @Override
    protected void onUnknownAction(Context context, Intent intent) {
        String action = intent.getAction();
        if (action == null) {
            return;
        }
        UsbAccessory device;
        if (action.equals(ACTION_USB_PERMISSION)) {
            Log.d("--->", "ACTION_USB_PERMISSION");
            Log.d(TAG, "ACTION_USB_PERMISSION");
            device = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
            boolean allowed = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false);
            if (!allowed) {
                Log.d(TAG, "usb device access permission not allowed");
                return;
            }
            if (listener != null) {
                listener.onDeviceAllowed(device);
            }
        } else {
            Log.d(TAG, "unknown action:" + action);
        }
    }

    public void onDestroy() {
        Log.d(TAG, "Usb Manager destroy");
        listener = null;
        ctx.unregisterReceiver(this);
        ctx = null;
        usbManager = null;
    }
}
